﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Game
{
    namespace RenderTechnique
    {
        class DeferredTechnique : PostProcessRenderTechnique
        {
            public DeferredTechnique(TechniqueDescription desc)
                : base(desc)
            {
            }

            public override void Init()
            {
                base.Init();

                InitSunShadow();

                InitOutput();

                // Step 1.0 : gen gbuffer
                IDK.ShaderProgram program = Description.Core.GetShaderProgram("DeferredShading\\GBuffer");
                mBaseShader = program;

                // Step 1.1 : add parameter
                program.AddParameter(IDK.ShaderProgram.Parameter.Type.VertexAttribute, IDK.ShaderProgram.Parameter.Declaration.VertexPosition, "position");
                program.AddParameter(IDK.ShaderProgram.Parameter.Type.VertexAttribute, IDK.ShaderProgram.Parameter.Declaration.VertexNormal, "normal");
                program.AddParameter(IDK.ShaderProgram.Parameter.Type.VertexAttribute, IDK.ShaderProgram.Parameter.Declaration.VertexTangent, "tangent");
                program.AddParameter(IDK.ShaderProgram.Parameter.Type.VertexAttribute, IDK.ShaderProgram.Parameter.Declaration.VertexTexCoord, "tcoord");

                program.AddParameter(IDK.ShaderProgram.Parameter.Type.ConstantParameter, IDK.ShaderProgram.Parameter.Declaration.MatrixProjection, "gProj");
                program.AddParameter(IDK.ShaderProgram.Parameter.Type.ConstantParameter, IDK.ShaderProgram.Parameter.Declaration.MatrixView, "gView");
                program.AddParameter(IDK.ShaderProgram.Parameter.Type.ConstantParameter, IDK.ShaderProgram.Parameter.Declaration.MatrixWorld, "gWorld");

                program.AddParameter(IDK.ShaderProgram.Parameter.Type.ConstantParameter, IDK.ShaderProgram.Parameter.Declaration.Texture0, "decalMap");
                program.AddParameter(IDK.ShaderProgram.Parameter.Type.ConstantParameter, IDK.ShaderProgram.Parameter.Declaration.Texture1, "bumpMap");


                // Step 1.2 Generate MultiRenderTarget
                IDK.RenderTarget renderTargetDS = Description.Core.GetRenderTarget("mrtDS");
                // Step 1.3 Attach texture in mrt

                renderTargetDS.AttachTexture(Description.Core.CreateRenderTexture(1024, 768, IDK.Texture.Format.RGBA, IDK.Texture.PixelType.FloatRGBA16));
                renderTargetDS.AttachTexture(Description.Core.CreateRenderTexture(1024, 768, IDK.Texture.Format.RGBA, IDK.Texture.PixelType.FloatRGBA16));
                
                //NOTE: if using old shader model than we need had same pixel format
                renderTargetDS.AttachTexture(Description.Core.CreateRenderTexture(1024, 768, IDK.Texture.Format.RGBA, IDK.Texture.PixelType.ByteRGBA8));

                //Step 2. Add screen ds
                IDK.ShaderProgram programScreen = Description.Core.GetShaderProgram("DeferredShading\\Screen");

                programScreen.AddParameter(IDK.ShaderProgram.Parameter.Type.ConstantParameter, IDK.ShaderProgram.Parameter.Declaration.MatrixViewInverse, "gViewInv");
                programScreen.AddParameterData(IDK.ShaderProgram.Parameter.Type.ConstantParameter, IDK.ShaderProgram.Parameter.Declaration.Constant44f, "gShadowMatrix", SunShadowLightMatrix);
                programScreen.AddParameter(IDK.ShaderProgram.Parameter.Type.ConstantParameter, IDK.ShaderProgram.Parameter.Declaration.Texture0, "gPosMap");
                programScreen.AddParameter(IDK.ShaderProgram.Parameter.Type.ConstantParameter, IDK.ShaderProgram.Parameter.Declaration.Texture1, "gNormalMap");
                programScreen.AddParameter(IDK.ShaderProgram.Parameter.Type.ConstantParameter, IDK.ShaderProgram.Parameter.Declaration.Texture2, "gColorMap");
                programScreen.AddParameter(IDK.ShaderProgram.Parameter.Type.ConstantParameter, IDK.ShaderProgram.Parameter.Declaration.Texture3, "gShadowMap");


                Description.Renderer.AddPass(new IDK.DeferredShadingPass(Description.Core.GetScene(), Description.Camera, renderTargetDS, RTTShadow, RTTOutput, programScreen));

                //Init Postprocess
                InitPostrocess();
            }
        }
    }
}
